package com.yonyou.pmclouds.plantemplate.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.billtype.util.BillTypeInfoQueryUtils;
import com.yonyou.pmclouds.billtype.util.DepartmentInfoQueryUtils;
import com.yonyou.pmclouds.outter.user.UserInfoQuery;
import com.yonyou.pmclouds.plan.entity.ScheduleItemVO;
import com.yonyou.pmclouds.plantemplate.entity.ScheduleTemplateItemVO;
import com.yonyou.pmclouds.plantemplate.entity.ScheduleTemplateVO;
import com.yonyou.pmclouds.plantemplate.entity.ScheduleTemplateViewVO;
import com.yonyou.pmclouds.plantemplate.rmiitf.IScheduleTemplateQueryService;
import com.yonyou.pmclouds.plantemplate.rmiitf.IScheduleTemplateService;
import com.yonyou.pmclouds.user.entity.UserInfo;
import com.yonyou.pmclouds.user.entity.UserSearchResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @Description: 进度计划模板WEB端
 * @Author: zhangzhonghao
 * @Date: 2020-03-06
 */

@Slf4j
@RestController
@RequestMapping("/schedule/template")
public class ScheduleTemplateController {

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private IScheduleTemplateService templateService;

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private IScheduleTemplateQueryService templateQueryService;

    @Autowired
    private BillTypeInfoQueryUtils billTypeInfoQueryUtils;

    @Autowired
    private DepartmentInfoQueryUtils departmentInfoQueryUtils;

    @Autowired
    private UserInfoQuery userInfoQuery;

    /**
     * 计划模板保存接口
     * @param templateVO 计划模板VO
     * @return 计划模板
     */
    @RequestMapping("/save")
    public ScheduleTemplateVO insert(@RequestBody ScheduleTemplateVO templateVO) throws BusinessException {
        return templateService.insert(templateVO);
    }

    /**
     * 计划模板删除接口
     * @param templateVO 计划模板VO
     * @return 计划模板VO
     */
    @RequestMapping("/delete")
    public ScheduleTemplateVO delete(@RequestBody ScheduleTemplateVO templateVO) throws BusinessException {
        return templateService.delete(templateVO);
    }

    /**
     * 通过计划模板主键查询计划详情接口，包含子表与关联项的值
     * @param pkScheduleTemplate 计划模板主键
     * @return 计划VO
     */
    @RequestMapping("/queryById")
    public ScheduleTemplateVO queryByPk(@RequestParam("pkScheduleTemplate") String pkScheduleTemplate) throws BusinessException {
        ScheduleTemplateVO templateVO = templateQueryService.queryById(pkScheduleTemplate);
        if (templateVO == null) {
            return null;
        }

        setRelatedValue(new ScheduleTemplateVO[]{templateVO});

        return templateVO;
    }

    @RequestMapping("/search")
    public List<ScheduleTemplateViewVO> search(@RequestParam("keyword") String keyword) throws BusinessException {
        ScheduleTemplateVO[] templateVOS = templateQueryService.searchTemplate(keyword);
        if (templateVOS == null || templateVOS.length <= 0) {
            return null;
        }

        setRelatedValue(templateVOS);

        Map<String, List<ScheduleTemplateVO>> typeTempMap = new HashMap<>();
        // 计划类型主键和名称的映射
        Map<String, String> typeNameMap = new HashMap<>();
        for(ScheduleTemplateVO vo : templateVOS){
            List<ScheduleTemplateVO> templateVOList = typeTempMap.get(vo.getType());
            if(templateVOList == null){
                templateVOList = new ArrayList<>();
                typeTempMap.put(vo.getType(), templateVOList);
            }
            templateVOList.add(vo);
            typeNameMap.put(vo.getType(), vo.getTypeName());
        }

        List<ScheduleTemplateViewVO> templateViewVOS = new ArrayList<>();
        for(Map.Entry<String, List<ScheduleTemplateVO>> entry : typeTempMap.entrySet()){
            ScheduleTemplateViewVO viewVO = new ScheduleTemplateViewVO();
            viewVO.setType(entry.getKey());
            viewVO.setTypeName(typeNameMap.get(entry.getKey()) == null ? entry.getKey() : typeNameMap.get(entry.getKey()));
            List<ScheduleTemplateVO> templateVOList = typeTempMap.get(entry.getKey());
            if(templateVOList != null && templateVOList.size() > 0){
                viewVO.setTemplateVOS(templateVOList.toArray(new ScheduleTemplateVO[]{}));
            }
            templateViewVOS.add(viewVO);
        }

        return templateViewVOS;
    }

    /**
     * 获取负责人集合（当前租户下的用户）
     */
    @GetMapping("/searchUser")
    @ResponseBody
    public UserInfo[] searchUser(@RequestParam(value = "keyword", required = false) String keyword) {
        UserSearchResultVO.ContentVO users = userInfoQuery.searchUsers(RuntimeEnvironment.getTenantId(), keyword,
                1, 1000);
        if (users == null)
            return new UserInfo[0];

        return users.getContent();
    }

    /**
     * 翻译关联项的值
     * @param templateVOS 计划
     */
    private void setRelatedValue(ScheduleTemplateVO[] templateVOS) throws BusinessException {
        Set<String> billTypeCodeSet = new HashSet<>();
        Set<String> pkDeptSet = new HashSet<>();
        List<ScheduleTemplateItemVO> itemVOS = new ArrayList<>();
        for (ScheduleTemplateVO templateVO : templateVOS) {
            for (ScheduleTemplateItemVO itemVO : templateVO.getScheduleTemplateItemVOS()) {
                getRelatedItem(itemVO, billTypeCodeSet, pkDeptSet, itemVOS);
            }
        }

        Map<String, String> billTypeNameMap = billTypeInfoQueryUtils.queryNameByType(
                billTypeCodeSet.toArray(new String[]{}));
        Map<String, String> departmentNameMap = departmentInfoQueryUtils.queryNameByPks(
                pkDeptSet.toArray(new String[]{}));

        for (ScheduleTemplateVO scheduleVO : templateVOS) {
            for (ScheduleTemplateItemVO itemVO : scheduleVO.getScheduleTemplateItemVOS()) {
                setRelatedItemValue(itemVO, billTypeNameMap, departmentNameMap);
            }
        }

        String[] itemUserFields = new String[]{ScheduleTemplateItemVO.MANAGER, ScheduleItemVO.CREATOR};
        String[] itemUserNameFields = new String[]{ScheduleItemVO.MANAGER_NAME, ScheduleItemVO.CREATOR_NAME};
        userInfoQuery.tranUserInfoField(itemVOS.toArray(new ScheduleTemplateItemVO[]{}), itemUserFields, itemUserNameFields);

        String[] scheduleUserFields = new String[]{ScheduleTemplateVO.CREATOR};
        String[] scheduleUserNameFields = new String[]{ScheduleTemplateVO.CREATOR_NAME};
        userInfoQuery.tranUserInfoField(templateVOS, scheduleUserFields, scheduleUserNameFields);
    }



    /**
     * 获取需要翻译的关联项
     *
     * @param itemVO      任务节点
     * @param billTypeSet 任务关联的单据类型
     * @param pkDeptSet   任务关联的责任部门
     * @param itemVOS     所有的子级，翻译人员名称使用
     */
    private void getRelatedItem(ScheduleTemplateItemVO itemVO, Set<String> billTypeSet, Set<String> pkDeptSet, List<ScheduleTemplateItemVO> itemVOS) {
        itemVOS.add(itemVO);

        if (StringUtils.isNotEmpty(itemVO.getRelatedBillType())) {
            billTypeSet.add(itemVO.getRelatedBillType());
        }

        if (StringUtils.isNotEmpty(itemVO.getPkDepartment())) {
            pkDeptSet.add(itemVO.getPkDepartment());
        }

        if (itemVO.getChildren() != null && itemVO.getChildren().length > 0) {
            for (ScheduleTemplateItemVO childItemVO : itemVO.getChildren()) {
                getRelatedItem(childItemVO, billTypeSet, pkDeptSet, itemVOS);
            }
        }
    }

    /**
     * 对关联项进行翻译赋值
     *
     * @param itemVO            任务项
     * @param billTypeNameMap   关联单据类型描述汇总
     * @param departmentNameMap 关联部门描述汇总
     */
    private void setRelatedItemValue(ScheduleTemplateItemVO itemVO, Map<String, String> billTypeNameMap, Map<String, String> departmentNameMap) {
        if (StringUtils.isNotEmpty(itemVO.getRelatedBillType())) {
            itemVO.setRelatedBillTypeName(billTypeNameMap.get(itemVO.getRelatedBillType()));
        }
        if (StringUtils.isNotEmpty(itemVO.getPkDepartment())) {
            itemVO.setDepartmentName(departmentNameMap.get(itemVO.getPkDepartment()));
        }

        if (itemVO.getChildren() != null && itemVO.getChildren().length > 0) {
            for (ScheduleTemplateItemVO childItemVO : itemVO.getChildren()) {
                setRelatedItemValue(childItemVO, billTypeNameMap, departmentNameMap);
            }
        }
    }
}
